package com.zjcode.cdcer.service.impl;

import com.chinatechstar.component.commons.entity.MPage;
import com.chinatechstar.component.commons.result.PaginationBuilder;
import com.chinatechstar.component.commons.service.BaseService;
import com.chinatechstar.component.commons.supports.PageData;
import com.chinatechstar.component.commons.utils.ExcelUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zjcode.cdcer.config.MConsts.Common;
import com.zjcode.cdcer.mapper.CerSysteminitImportOfficialInfoMapper;
import com.zjcode.cdcer.model.TkmEndoscopeDiagnoseNounInfo;
import com.zjcode.cdcer.model.basic.JsonObj;
import com.zjcode.cdcer.pojo.CerSysteminitImportInfo;
import com.zjcode.cdcer.model.CerSysteminitImportOfficialInfo;
import com.zjcode.cdcer.model.SysDict;
import com.zjcode.cdcer.service.*;
import com.zjcode.cdcer.utils.Utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class CerSysteminitImportOfficialInfoServiceImpl implements
                                                        CerSysteminitImportOfficialInfoService,
                                                        BaseService {

    @Autowired
    private CerSysteminitImportOfficialInfoMapper cerSysteminitImportOfficialInfoMapper;
    @Autowired
    private CerSysteminitImportInfoService cerSysteminitImportInfoService;
    @Autowired
    private CerDetaildataImportInfoService cerDetaildataImportInfoService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysDictService sysDictService;

    @Autowired
    private TkmEndoscopeDiagnoseNounInfoService endoscopeDiagnoseNounInfoService;

    @Override
    public JsonObj insertOfficeInfo(PageData pageData) {

        Map<String, Object> data = new HashMap<>();
        data.put("count", 0);
        // 获取初始数据上报中的数据
        List<CerSysteminitImportInfo> list = cerSysteminitImportInfoService.getAllNoErrorData(
            pageData);
        if (!CollectionUtils.isEmpty(list)) {

            List<CerSysteminitImportInfo> officialtList = new ArrayList<>();

            // 遍历出ext_flag_2不是0|0|0的数据
            List<CerSysteminitImportInfo> tmpList1 = list
                .stream()
                .filter(each -> {
                    String extFlag2 = each.getExtFlag2();
                    return !StringUtils.equals(extFlag2, "0|0|0");
                })
                .collect(Collectors.toList());

            officialtList.addAll(tmpList1);

            // 遍历list,通过组装出最高诊断代码,判断出需要插入到officialtList中的数据
            List<CerSysteminitImportInfo> tmpList2 = list
                .stream()
                .filter(each -> {
                    String maxCode = each.getMaxCode();
                    String[] split = maxCode.split("\\|");
                    boolean bo = false;
                    // 此处之所以为3,表示12指肠的诊断代码不再判断之内
                    for (int i = 0; i < 3; i++) {
                        String s = split[i];
                        long count = Common.DIAGNOSTIC_CODE_LIST
                            .stream()
                            .filter(str -> {
                                boolean equals = str.equals(s);
                                if (equals) {
                                    log.info("诊断代码:{}-{}", s, str);
                                }
                                return equals;
                            })
                            .count();
                        if (count > 0) {
                            bo = true;
                            break;
                        }
                    }

                    return bo;
                })
                .collect(Collectors.toList());

            if (!CollectionUtils.isEmpty(tmpList2)) {
                // 去重
                tmpList2.removeIf(each -> {
                    long count = officialtList
                        .stream()
                        .filter(each2 -> {
                            return each2
                                .getId()
                                .equals(each.getId());
                        })
                        .count();
                    return count > 0;
                });
                officialtList.addAll(tmpList2);
            }

            // 移除list中将要被上传到详情数据表的数据
            list.removeAll(officialtList);

            // 针对详情库中的数据进行错误验证
            officialtList
                .parallelStream()
                .forEach(each -> {
                    String extFlag2 = each.getExtFlag2();
                    if (StringUtils.isEmpty(extFlag2)) {
                        // 构造出extflag2
                        // 获取食管病理诊断代码
                        extFlag2 = getExtFlag2(each);
                        each.setExtFlag2(extFlag2);
                    }

                });

            // 插入初始数据正式库
            if (CollectionUtils.isNotEmpty(list)) {
                cerSysteminitImportOfficialInfoMapper.insertOfficeInfo(list);
            }

            // 插入详情数据上报库
            if (CollectionUtils.isNotEmpty(officialtList)) {
                cerDetaildataImportInfoService.batchInsert(officialtList);
            }

            int count = list.size() + officialtList.size();
            data.put("count", count);

            // 修改原初始数据上报库中的数据状态
            cerSysteminitImportInfoService.updateCerSysteminitImportInfoStatus(pageData);
            return JsonObj.success(data);
        }
        return JsonObj.success(data);
    }

    @Override
    public Map<String, Object> listAllTableData(PageData pageData) {
        String userId = (String) pageData.get("user");
        if (StringUtils.isNotEmpty(userId)) {
            String extFlag = sysUserService.findUserExtFlag(userId);
            pageData.put("extFlag", extFlag);
        }
        // 读取区域信息
        pageData = Utils.transitionRegionInfo(pageData);
        MPage mPage = getPageInfo(pageData);
        List<SysDict> allCerDicts = sysDictService.findAllCerDicts();
        Map<String, List<SysDict>> keyListMap = allCerDicts
            .stream()
            .collect(Collectors.groupingBy(SysDict::getDictType));
        Page<Object> page = PageHelper.startPage(mPage.getCurrentPage(), mPage.getPageSize());
        List<LinkedHashMap<String, Object>> mapList = cerSysteminitImportOfficialInfoMapper.listAllTableData(
            pageData);
        keyListMap
            .entrySet()
            .parallelStream()
            .forEach(entry -> {
                // key
                String key = entry.getKey();
                if (key.equals("xb_code")) {
                    key = "sex";
                }
                List<SysDict> dicts = entry.getValue();
                String finalKey = key;
                mapList
                    .stream()
                    .forEach(map -> {
                        String obj = String.valueOf(map.get(finalKey));
                        if (obj != null) {
                            Optional<SysDict> first = dicts
                                .stream()
                                .filter(sysDict -> sysDict
                                    .getDictValue()
                                    .equals(obj))
                                .findFirst();
                            first.ifPresent(sysDict -> {
                                map.put(finalKey, sysDict.getDictName());
                            });
                        }
                    });
            });

        // 还原内镜诊断
        mapList
            .parallelStream()
            .forEach(map -> {
                String njzd = (String) map.get("njzd");
                List<String> ids = Arrays.asList(njzd.split(","));
                List<TkmEndoscopeDiagnoseNounInfo> nounInfos = endoscopeDiagnoseNounInfoService.selectByNounIds(
                    ids);
                if (nounInfos != null) {
                    map.put("njzd",
                            nounInfos
                                .stream()
                                .map(TkmEndoscopeDiagnoseNounInfo::getName)
                                .collect(Collectors.joining(",")));
                } else {
                    map.put("njzd", "");
                }
            });

        // 身份证, 给身份证加上掩码
        mapList
            .parallelStream()
            .forEach(each -> {
                String sfz = (String) each.get("sfz");
                if (sfz != null) {
                    each.put("sfz", sfz.substring(0, 6) + "********" + sfz.substring(14));
                }
            });

        return PaginationBuilder.buildResult(mapList,
                                             page.getTotal(),
                                             mPage.getCurrentPage(),
                                             mPage.getPageSize());
    }

    @Override
    public CerSysteminitImportOfficialInfo findDataById(String id) {
        return cerSysteminitImportOfficialInfoMapper.findDataById(id);
    }

    @Override
    public List<LinkedHashMap<String, Object>> queryAllExportDataBy(PageData pageData) {

        String userId = (String) pageData.get("user");
        String ids = (String) pageData.get("ids");

        String extFlag = sysUserService.findUserExtFlag(userId);
        pageData.put("extFlag", extFlag);

        List<SysDict> allCerDicts = sysDictService.findAllCerDicts();
        Map<String, List<SysDict>> keyListMap = allCerDicts
            .stream()
            .collect(Collectors.groupingBy(SysDict::getDictType));

        // 获取ids
        List<String> idList = new ArrayList<>();
        if (!StringUtils.isEmpty(userId)) {
            idList.addAll(Arrays.asList(ids.split("\\|")));
            pageData.put("idList", idList);
        }

        List<LinkedHashMap<String, Object>> infoList = cerSysteminitImportOfficialInfoMapper.queryAllExportData(
            pageData);

        keyListMap
            .entrySet()
            .parallelStream()
            .forEach(entry -> {
                // key
                String key = entry.getKey();
                if (key.equals("xb_code")) {
                    key = "sex";
                }
                List<SysDict> dicts = entry.getValue();
                String finalKey = key;
                infoList
                    .stream()
                    .forEach(map -> {
                        Object o = map.get(finalKey);
                        if (o != null) {
                            Optional<SysDict> first = dicts
                                .stream()
                                .filter(sysDict -> sysDict
                                    .getDictValue()
                                    .equals(o.toString()))
                                .findFirst();
                            first.ifPresent(sysDict -> {
                                map.put(finalKey,
                                        Optional
                                            .ofNullable(sysDict.getDictName())
                                            .orElse(""));
                            });
                        }
                    });
            });
        return infoList;
    }

    /**
     * 获取所有合格初始数据正式库的数据集合
     */
    @Override
    public JsonObj getNoErrorOfficeData() {
        //List<CerSysteminitImportOfficialInfo> data = cerSysteminitImportOfficialInfoMapper.getNoErrorOfficeData();
        //if (!org.springframework.util.CollectionUtils.isEmpty(data)) {
        //    List<CerSysteminitImportOfficialInfo> collect = data
        //        .stream()
        //        .parallel()
        //        .map(obj -> {
        //            obj.setId(get32UUID());
        //            return obj;
        //        })
        //        .collect(Collectors.toList());
        //    //插入详情数据上报数据表
        //    int result = cerDetaildataImportInfoService.batchInsert(collect);
        //    if (result > 0) {
        //        //插入成功
        //        return JsonObj.success("已保存！");
        //    }
        //}
        return JsonObj.success("保存失败！");
    }

    @Override
    public void exportInitOfficialForGJMode(PageData pageData, HttpServletResponse response) {
        String userId = (String) pageData.get("user");
        Object idsData = pageData.get("ids");
        String extFlag = sysUserService.findUserExtFlag(userId);
        pageData.put("extFlag", extFlag);
        List<String> ids = new ArrayList<>();
        if (ObjectUtils.isNotEmpty(idsData)) {
            ids = Arrays.asList(String.valueOf(idsData).split("\\|"));
        }
        List<LinkedHashMap<String, Object>> list = cerSysteminitImportOfficialInfoMapper.selectInitOfficialForGJMod(ids,idsData,pageData);
        cerSysteminitImportInfoService.setCommonExportData(list);
        // 组装表头
        List<String> headList = Arrays.asList(
                "省份",
                "城市",
                "区县",
                "机构名称",
                "姓名",
                "性别",
                "年龄",
                "身份证号",
                "地址",
                "联系电话",
                "门诊号",
                "住院号",
                "内镜诊疗日期",
                "对象来源",
                "内镜号",
                "是否无痛",
                "染色类别",
                "图片数量",
                "是否活检",
                "Hp",
                "Hp检测方法",
                "内镜诊断",
                "内镜诊断医师",
                "内镜审核医师",
                "病理号",
                "病理诊断",
                "食管病理诊断代码",
                "贲门病理诊断代码",
                "胃病理诊断代码",
                "十二指肠病理诊断代码",
                "病理诊断医师",
                "病理审核医师",
                "病理报告日期",
                "上传时间");
        try {
            // 导出
            ExcelUtils.exportExcel(headList, list, "初始正式库导出（国家平台导出模板格式）", response);
        } catch (Exception e) {
            log.info("导入失败，原因：", e);
        }
    }

    private int getFlagByCode(String code) {
        if (StringUtils.isEmpty(code)) {
            return 0;
        }
        long count = Common.DIAGNOSTIC_CODE_LIST
            .stream()
            .filter(c -> {
                return c.equals(code);
            })
            .count();
        if (count > 0) {
            return 1;
        }
        return 0;
    }

    private String getExtFlag2(CerSysteminitImportInfo each) {
        String extFlag2;
        List<Integer> flags = new ArrayList<>();
        String sgblCode = each.getSgblCode();
        flags.add(getFlagByCode(sgblCode));
        // 获取贲门病理诊断代码
        String bmblCode = each.getBmblCode();
        flags.add(getFlagByCode(bmblCode));
        // 获取胃病理诊断代码
        String wblCode = each.getWblCode();
        flags.add(getFlagByCode(wblCode));
        extFlag2 = flags
            .stream()
            .map(String::valueOf)
            .collect(Collectors.joining(Common.DELIMITER_CHARACTER));
        return extFlag2;
    }
}
